-
-
Notifications
You must be signed in to change notification settings - Fork 362
fix(Input): prevent focus exception #6920
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Reviewer's guide (collapsed on small PRs)Reviewer's GuideThis PR replaces the ElementReference-based focus logic with a safe JavaScript helper that retrieves elements by ID and focuses them conditionally, removing all @ref bindings and the FocusElement property to prevent focus-related exceptions. Class diagram for BootstrapInputBase focus logic refactorclassDiagram
class BootstrapInputBase {
- string CssClass
- string ValidCss
- string PlaceHolder
- string Type
- string Id
- string EventString
- string CurrentValueAsString
- string Disabled
- string ReadonlyString
- string AdditionalAttributes
- string ClassName
- string OnBlur
- string GetInputId()
+ Task FocusAsync()
+ Task SelectAsync()
}
%% Removed property
%% FocusElement property was removed
%% FocusAsync method was updated to use JS helper instead of ElementReference
Flow diagram for new focus logic using JavaScript helperflowchart TD
A["Component calls FocusAsync()"] --> B["InvokeVoidAsync('focus', GetInputId())"]
B --> C["BootstrapInput.razor.js: focus(id)"]
C --> D["document.getElementById(id)"]
D --> E{Element found?}
E -- Yes --> F["el.focus()"]
E -- No --> G["Do nothing"]
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR prevents focus exceptions in Input components by refactoring the focus mechanism from using ElementReference to JavaScript DOM APIs. The change addresses issue #6894 by removing direct element references that could cause exceptions.
Key changes:
- Replaced
@ref="FocusElement"with JavaScript-based focus implementation - Introduced a new
focusfunction in the JavaScript module - Updated version to 9.11.3-beta02
Reviewed Changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| BootstrapInputBase.cs | Removed FocusElement property and updated FocusAsync to use JavaScript |
| BootstrapInput.razor.js | Added new focus function for DOM-based element focusing |
| Multiple .razor files | Removed @ref="FocusElement" from input elements |
| BootstrapBlazor.csproj | Version bump to 9.11.3-beta02 |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| export function focus(id) { | ||
| const el = document.getElementById(id) | ||
| if (el) { | ||
| el.focus(); |
Copilot
AI
Oct 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The focus function should handle cases where the element is not found or cannot be focused. Consider adding error handling or logging when the element doesn't exist or focus fails.
| el.focus(); | |
| try { | |
| el.focus(); | |
| } catch (err) { | |
| console.error(`Failed to focus element with id '${id}':`, err); | |
| } | |
| } else { | |
| console.warn(`Element with id '${id}' not found. Cannot focus.`); |
| /// </summary> | ||
| /// <returns></returns> | ||
| public async Task FocusAsync() => await FocusElement.FocusAsync(); | ||
| public async Task FocusAsync() => await InvokeVoidAsync("focus", GetInputId()); |
Copilot
AI
Oct 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The FocusAsync method should handle potential JavaScript invocation failures. Consider wrapping in try-catch or returning a result indicating success/failure to maintain the async contract's reliability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there - I've reviewed your changes and they look great!
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location> `src/BootstrapBlazor/Components/Input/BootstrapInput.razor.js:3-8` </location>
<code_context>
import EventHandler from "../../modules/event-handler.js"
+export function focus(id) {
+ const el = document.getElementById(id)
+ if (el) {
+ el.focus();
+ }
+}
+
</code_context>
<issue_to_address>
**suggestion:** The focus function does not handle elements that are not focusable.
Check if the element is focusable before calling el.focus(), or handle potential exceptions to prevent errors.
```suggestion
export function focus(id) {
const el = document.getElementById(id)
if (el) {
// Check if element is focusable
const isNaturallyFocusable = (
el instanceof HTMLInputElement ||
el instanceof HTMLButtonElement ||
el instanceof HTMLSelectElement ||
el instanceof HTMLTextAreaElement ||
(el instanceof HTMLAnchorElement && el.hasAttribute("href"))
);
if (isNaturallyFocusable || el.tabIndex >= 0) {
try {
el.focus();
} catch (e) {
// Optionally log or handle the error
}
}
}
}
```
</issue_to_address>
### Comment 2
<location> `src/BootstrapBlazor/Components/Input/BootstrapInput.razor.js:4` </location>
<code_context>
import EventHandler from "../../modules/event-handler.js"
+export function focus(id) {
+ const el = document.getElementById(id)
+ if (el) {
+ el.focus();
</code_context>
<issue_to_address>
**issue (bug_risk):** Using getElementById assumes unique IDs across the DOM.
If IDs are not unique, focusing may target the wrong element. Confirm that GetInputId() produces unique IDs for every input.
</issue_to_address>
### Comment 3
<location> `src/BootstrapBlazor/Components/Textarea/Textarea.razor:11` </location>
<code_context>
}
<textarea @attributes="AdditionalAttributes" placeholder="@PlaceHolder" id="@Id" class="@ClassName" disabled="@Disabled"
@bind-value="CurrentValueAsString" @bind-value:event="@EventString" @onblur="@OnBlur"
- data-bb-shift-enter="@ShiftEnterString" data-bb-scroll="@AutoScrollString" @ref="FocusElement"></textarea>
+ data-bb-shift-enter="@ShiftEnterString" data-bb-scroll="@AutoScrollString"></textarea>
</code_context>
<issue_to_address>
**question:** Textarea loses direct reference, which may affect programmatic focus or selection.
Please ensure the JS-based solution allows programmatic focus and selection of the textarea as reliably as the previous @ref approach.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6920 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 740 740
Lines 31847 31811 -36
Branches 4468 4468
=========================================
- Hits 31847 31811 -36
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Link issues
fixes #6894
Summary By Copilot
Regression?
Risk
Verification
Packaging changes reviewed?
☑️ Self Check before Merge
Summary by Sourcery
Prevent focus exceptions by replacing Blazor element references with a safe JS interop focus call across input components
Bug Fixes:
Enhancements:
Chores: